// 问题4：对比新旧节点差异
import { createElementDom } from './createElementDom'
import { diffComponent } from './diffComponent.js'
import { mountElement } from './mountElement'
import { unmountNode } from './unmountNode'
import { updateNodeElement } from './updateNodeElement'
import { updateTextNode } from './updateTextNode'

export function diff (vdom, container, oldDom) {
  // 从真实dom拿vdom
  const oldVdom = oldDom && oldDom._vdom
  const oldComponent = oldVdom && oldVdom.component
  if (!oldDom) {
    mountElement(vdom, container)
  } else if (vdom.type !== oldVdom.type && typeof vdom.type !== 'function') {
    const newEle = createElementDom(vdom)
    oldDom.parentNode.replaceChild(newEle, oldDom)
  } else if (typeof vdom.type === 'function') {
    diffComponent(vdom, oldComponent, oldDom, container)
  } else if (oldVdom && vdom.type === oldVdom.type) {

    // 两元素相同
    if (vdom.type === 'text') {
      // 文本节点
      updateTextNode(vdom, oldVdom, oldDom)
    } else {
      // 元素节点 --- 写好的给元素添加属性的方法
      updateNodeElement(oldDom, vdom, oldVdom)
    }

    /* 
    比对方式
    1. 下标比对（默认）
    2. key比对
      2.1 keyedElements
    */
    //2.1
    let keyedElements = {}
    for (let i = 0, len = oldDom.childNodes.length; i < len; i++) {
      let domElement = oldDom.childNodes[i]
      if (domElement.nodeType === 1) {//1是元素节点，才有key属性
        let key = domElement.getAttribute("key")
        key && (keyedElements[key] = domElement)
      }
    }
    let hasNoKey = Object.keys(keyedElements).length === 0
    if (hasNoKey) {
      // 1
      vdom.children.forEach((child, i) => {
        diff(child, oldDom, oldDom.childNodes[i])
      })
    } else {
      // 2
      vdom.children.forEach((child, i) => {
        let key = child.props.key
        if (key) {
          let domElement = keyedElements[key]
          if (domElement) {
            // 3. 看看当前位置的元素不是我们期望的元素,插入当前元素前面，给元素安排正确的位置
            if (oldDom.childNodes[i] && oldDom.childNodes[i] !== domElement) {
              oldDom.insertBefore(domElement, oldDom.childNodes[i])
            }
          } else {
            // 有key的新增元素
            mountElement(child, oldDom, oldDom.childNodes[i])
          }
        }
      })
    }




    // 删除子节点
    const oldChildNodes = oldDom.childNodes;
    const oldLen = oldChildNodes.length
    const nextLen = vdom.children.length
    if (oldLen > nextLen) {
      if (hasNoKey) {
        for (let i = oldLen - 1; i > nextLen - 1; i--) {
          unmountNode(oldChildNodes[i])//卸载节点
        }
      } else {
        // key删除
        for (let i = 0; i < oldLen; i++) {
          let oldChild = oldChildNodes[i]
          let oldChildKey = oldChild._vdom.props.key
          let found = vdom.children.some(item => oldChildKey === item.props.key)
          !found && unmountNode(oldChild)
        }
      }
    }

  }
}